#include "ecgprocess.h"
#include "ui_ecgprocess.h"
#include "shareAlg/wavelet/waveletfilter.h"
#include "QFileDialog"
#include "dll/MultiUSBDongleLib.h"
#include <iostream>
#include <fstream>
#include "dll/iirfilter.h"
#include <algorithm> // 包含max_element和min_elemen
#include "shareAlg/arrayOper/arrayoperation.h"
#include <Eigen/Dense>

ECGProcess::ECGProcess(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ECGProcess)
{
    ui->setupUi(this);

    initWave();
    initControls();
    initMulti_USBDongle();

    ecgRExtract=new ECGRWaveExtract();

}

ECGProcess::~ECGProcess()
{
    delete ecgRExtract;
    delete ui;
}

void ECGProcess::initWave()
{
    ui->widget_ecgRaw->addGraph();
    ui->widget_ecgRaw->graph(0)->setPen(QPen(Qt::blue)); // 设置初始曲线颜色
    // 启用交互功能
    ui->widget_ecgRaw->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
    ui->widget_ecgRaw->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
    // ui->widget_ecgRaw->setInteraction(QCP::iRangeDrag, true);
    ui->widget_ecgRaw->setNoAntialiasingOnDrag(true);
    // 设置坐标轴标签
    ui->widget_ecgRaw->xAxis->setLabel("Samples");
    ui->widget_ecgRaw->yAxis->setLabel("Amplitude");


    ui->widget_filterECG->addGraph();
    ui->widget_filterECG->graph(0)->setPen(QPen(Qt::blue)); // 设置初始曲线颜色
    QCPGraph *graph = ui->widget_filterECG->addGraph();
    graph->setLineStyle(QCPGraph::lsNone); // 启用线条连接
    graph->setScatterStyle(QCPScatterStyle::ssCircle); // 设置点的样式为圆圈
    ui->widget_filterECG->graph(1)->setPen(QPen(Qt::red,2)); // 设置初始曲线颜色
    // 启用交互功能
    ui->widget_filterECG->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
    ui->widget_filterECG->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
    // ui->widget_filterECG->setInteraction(QCP::iRangeDrag, true);
    ui->widget_filterECG->setNoAntialiasingOnDrag(true);
    // 设置坐标轴标签
    ui->widget_filterECG->xAxis->setLabel("Samples");
    ui->widget_filterECG->yAxis->setLabel("Amplitude");

}

void ECGProcess::initControls()
{
    //限制输入数字
    ui->lineEdit_filter1_low->setValidator(new QDoubleValidator(this));
    ui->lineEdit_filter1_high->setValidator(new QDoubleValidator(this));
    ui->lineEdit_filter2_low->setValidator(new QDoubleValidator(this));
    ui->lineEdit_filter2_high->setValidator(new QDoubleValidator(this));
    ui->lineEdit_waveletDeLever->setValidator(new QIntValidator(1,12,this));

    ui->lineEdit_filter1_high->setEnabled(false);
    ui->lineEdit_filter2_high->setEnabled(false);
}

void ECGProcess::initMulti_USBDongle()
{
    MultiUSBDongle_init();
    QByteArray ecgMac=Hexstring2QByteArray("E0F883661402");
    QByteArray dualeegMac=Hexstring2QByteArray("D8035158F16A");

    MultiUSBDongle_setECG_HolterMac(reinterpret_cast<unsigned char*>(ecgMac.data()));
    MultiUSBDongle_setDualEEGMac(reinterpret_cast<unsigned char*>(dualeegMac.data()));
    MultiUSBDongle_setBioEEGOXDevice_ShowRawSignal(1);
}
QByteArray ECGProcess::Hexstring2QByteArray(QString str)
{
    QByteArray Hexstr;
    bool ok;
    for (int i = 0; i < str.size(); i += 2)
    {
        Hexstr.append((char)str.mid(i, 2).toInt(&ok, 16));
    }
    return Hexstr;
}
void ECGProcess::on_pushButton_selectFile_clicked()
{
    QString selFileName = QFileDialog::getOpenFileName(
        this,
        tr("选择原始信号文件"),
        QDir::currentPath(),
        tr("txt文档 (*.txt)")
        );
    if(selFileName.size()>0)
    {
        ui->lineEdit_Path->setText(selFileName);
    }


    QFile aFile(selFileName);
    if (aFile.exists())
    {
        qDebug()<<"selFileName.exists()";
        if(aFile.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            qDebug()<<"selFileName.open()";
            QTextStream aStream(&aFile); //用文本流读取文件
            QString s=aStream.readAll();
            aFile.close();//关闭文件
            QByteArray bufData=Hexstring2QByteArray(s);
            int len=bufData.size();
            int frameLen=100;
            int segNum=len/frameLen;
            rawecgWaves.clear();
            ecgWaves_x.clear();
            // 添加数据
            int k=0;
            for(int i=0;i<segNum;i++)
            {
                QByteArray subData=bufData.mid(i*frameLen,frameLen);
                unsigned char *p_subComData=(unsigned char *)subData.data();
                double ecgWave[100]={0}; double respWave[100]={0};int ecg_respLen[1]={0};
                double leftEEGWave[100]={0}; double rightEEGWave[100]={0}; double irWave[100]={0}; double appgWave[100]={0};int eeg_ppgLen[1]={0};
                MultiUSBDongle_TransData(p_subComData, frameLen, ecgWave, respWave, ecg_respLen, leftEEGWave, rightEEGWave, irWave, appgWave, eeg_ppgLen);
                for(int j=0;j<ecg_respLen[0];j++){
                    rawecgWaves.append(ecgWave[j]);
                    ecgWaves_x.append(k++);
                    if(yAxisminv>ecgWave[j])
                        yAxisminv=ecgWave[j];
                    if(yAxismaxv<ecgWave[j])
                        yAxismaxv=ecgWave[j];
                }
            }
            ui->lineEdit_Datalen->setText(QString::number(k/250)+"秒");
            ui->widget_ecgRaw->graph(0)->setData(ecgWaves_x, rawecgWaves);
            ui->widget_ecgRaw->xAxis->setRange(0, k);
            ui->widget_ecgRaw->yAxis->setRange(yAxisminv, yAxismaxv);
            ui->widget_ecgRaw->replot();
        }
    }

}


void ECGProcess::on_comboBox_filter1_currentIndexChanged(int index)
{
    ui->lineEdit_filter1_high->setEnabled(index>=2);
    if(index==0)
    {
        ui->lineEdit_filter1_low->setText("15");
    }else if(index==1)
    {
        ui->lineEdit_filter1_low->setText("0.25");
    }else if(index==2)
    {
        ui->lineEdit_filter1_low->setText("0.25");
        ui->lineEdit_filter1_high->setText("15");
    }else
    {
        ui->lineEdit_filter1_low->setText("49");
        ui->lineEdit_filter1_high->setText("51");
    }
}


void ECGProcess::on_comboBox_filter2_currentIndexChanged(int index)
{
    ui->lineEdit_filter2_high->setEnabled(index>=2);
    if(index==0)
    {
        ui->lineEdit_filter2_low->setText("15");
    }else if(index==1)
    {
        ui->lineEdit_filter2_low->setText("0.25");
    }else if(index==2)
    {
        ui->lineEdit_filter2_low->setText("0.25");
        ui->lineEdit_filter2_high->setText("15");
    }else
    {
        ui->lineEdit_filter2_low->setText("49");
        ui->lineEdit_filter2_high->setText("51");
    }
}

void ECGProcess::mousePressEvent(QMouseEvent *event)
{
    // if (event->modifiers() & Qt::ControlModifier) {
    //     ui->widget_ecgRaw->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
    // } else {
    //     ui->widget_ecgRaw->setSelectionRectMode(QCP::SelectionRectMode::srmNone);
    // }
}

QString ECGProcess::CharArrayToHexString(QByteArray Buffer,int Len)
{
    QString buf;
    for(int i=0;i<Len;i++){
        QString str = QString("%1").arg(Buffer[i]&0xFF,2,16,QLatin1Char('0')).toUpper() + QString("");   //2 字符宽度
        buf += str;
    }
    return buf;
}

void ECGProcess::on_pushButton_selectFile_2_clicked()
{
    if(ui->checkBox_selectfilter1->isChecked() || ui->checkBox_selectfilter2->isChecked() ||ui->checkBox_selectwaveletfilter->isChecked())
    {
        if(ui->checkBox_selectfilter1->isChecked())
        {
            IIRFilter *iirfilter=new IIRFilter(ui->comboBox_filter1->currentIndex(),250,ui->lineEdit_filter1_low->text().toDouble(),ui->lineEdit_filter1_high->text().toDouble());
            filterecgWaves1.clear();
            int len=rawecgWaves.length();
            for(int i=0;i<10000;i++)
                iirfilter->filter(rawecgWaves[0]);
            for(int i=0;i<len;i++){
                filterecgWaves1.append(iirfilter->filter(rawecgWaves[i]));
            }
            delete iirfilter;
        }else{
            filterecgWaves1.clear();
            filterecgWaves1.append(rawecgWaves);
        }
        if(ui->checkBox_selectfilter2->isChecked())
        {
            IIRFilter *iirfilter=new IIRFilter(ui->comboBox_filter2->currentIndex(),250,ui->lineEdit_filter2_low->text().toDouble(),ui->lineEdit_filter2_high->text().toDouble());
            filterecgWaves2.clear();
            int len=filterecgWaves1.length();
            for(int i=0;i<10000;i++)
                iirfilter->filter(filterecgWaves1[0]);
            for(int i=0;i<len;i++){
                filterecgWaves2.append(iirfilter->filter(filterecgWaves1[i]));
            }
            delete iirfilter;

        }else{
            filterecgWaves2.clear();
            filterecgWaves2.append(filterecgWaves1);
        }

        if(ui->checkBox_selectwaveletfilter->isChecked())
        {
            // 创建小波滤波对象（分解层数为3）
            int wfi=ui->comboBox_WaveletFunction->currentIndex();
            WaveletFunction wf;
            if(wfi==0)
            {
                wf=WaveletFunction::DB4;
            }else if(wfi==1)
            {
                wf=WaveletFunction::SYM8;
            }else
                wf=WaveletFunction::BIOR44;

            int ci=ui->comboBox_ThresholdRule->currentIndex();
            ThresholdRule tsr;
            if(ci==0)
            {
                tsr=ThresholdRule::UNIVERSAL;
            }else if(ci==1)
            {
                tsr=ThresholdRule::SURE;
            }else{
                tsr=ThresholdRule::HYBRID;
            }

            WaveletFilter filter(wf, tsr, ui->lineEdit_waveletDeLever->text().toInt());
            // 执行滤波
            filterecgWaves3 = filter.filter(filterecgWaves2);
        }else{
            filterecgWaves3.clear();
            filterecgWaves3.append(filterecgWaves2);
        }

        // 获取最大值最小值
        double maxValue;double minValue;
        ArrayOperation::instance().maximum(filterecgWaves3,maxValue,minValue);

        qDebug()<<"maxValue="<<maxValue<<",minValue="<<minValue;
        ui->widget_filterECG->graph(0)->setData(ecgWaves_x, filterecgWaves3);
        ui->widget_filterECG->xAxis->setRange(0, filterecgWaves3.size());
        ui->widget_filterECG->yAxis->setRange(minValue, maxValue);
        ui->widget_filterECG->replot();
    }else
    {
        QMessageBox::about(this,"温馨提示","请您至少选择一个滤波！");
    }

}


void ECGProcess::on_pushButton_close_clicked()
{
    this->close();
}




void ECGProcess::on_pushButton_R_feats_clicked()
{
    QVector<int>RPos;
    ecgRExtract->ECG_R_Extract(filterecgWaves3,RPos);
    int RPos_Len=RPos.size();

    QVector<double>RPos_Val,RPos_x;
    for(int i=0;i<RPos_Len;i++){
        RPos_x.append(RPos.at(i));
        RPos_Val.append(filterecgWaves3.at(RPos.at(i)));
    }
    ui->widget_filterECG->graph(1)->setData(RPos_x, RPos_Val);

    ui->widget_filterECG->replot();
    QFile file_info;
    file_info.setFileName("C:/Users/haibi/Desktop/rr.txt");
    if (file_info.open(QIODevice::WriteOnly  | QIODevice::Text)) {
        QTextStream stream;
        stream.setDevice(&file_info);
        for(int i=0;i<RPos_Len-1;i++)
        {
            stream<<RPos.at(i+1)-RPos.at(i)<<"\r\n";
        }
    }
    file_info.close();
}

